﻿using System;
using System.Runtime.InteropServices;
using System.Security;

namespace YJKBatchPrinter
{
	public class CSPrinterState
	{
		public static string GetPrinterStatus(string PrinterName)
		{
			int printerStatusInt = CSPrinterState.GetPrinterStatusInt(PrinterName);
			string empty = string.Empty;
			int num = printerStatusInt;
			if (num <= 4096)
			{
				if (num <= 128)
				{
					if (num <= 16)
					{
						switch (num)
						{
						case 0:
							return "准备就绪（Ready）";
						case 1:
							return "暂停（Paused）";
						case 2:
							return "错误(Printer Error）";
						case 3:
						case 5:
						case 6:
						case 7:
							break;
						case 4:
							return "正在删除（Pending Deletion）";
						case 8:
							return "塞纸（Paper Jam）";
						default:
							if (num == 16)
							{
								return "打印纸用完（Paper Out）";
							}
							break;
						}
					}
					else
					{
						if (num == 32)
						{
							return "手工送纸（Manual Feed）";
						}
						if (num == 64)
						{
							return "纸张问题（Page Problem）";
						}
						if (num == 128)
						{
							return "脱机（Off Line）";
						}
					}
				}
				else if (num <= 512)
				{
					if (num == 256)
					{
						return "正在输入,输出（I/O Active）";
					}
					if (num == 512)
					{
						return "忙(Busy）";
					}
				}
				else
				{
					if (num == 1024)
					{
						return "正在打印（Printing）";
					}
					if (num == 2048)
					{
						return "输出口已满（Output Bin Full）";
					}
					if (num == 4096)
					{
						return "不可用（Not Available）";
					}
				}
			}
			else if (num <= 262144)
			{
				if (num <= 32768)
				{
					if (num == 16384)
					{
						return "正在处理（Processing）";
					}
					if (num == 32768)
					{
						return "初始化(Initializing）";
					}
				}
				else
				{
					if (num == 65536)
					{
						return "热机中（Warming Up）";
					}
					if (num == 131072)
					{
						return "墨粉不足（Toner Low）";
					}
					if (num == 262144)
					{
						return "无墨粉（No Toner）";
					}
				}
			}
			else if (num <= 1048576)
			{
				if (num == 524288)
				{
					return "当前页无法打印（Page Punt）";
				}
				if (num == 1048576)
				{
					return "需要用户干预（User Intervention）";
				}
			}
			else
			{
				if (num == 2097152)
				{
					return "内存溢出（Out of Memory）";
				}
				if (num == 4194304)
				{
					return "被打开（Printer Door Open）";
				}
				if (num == 536870912)
				{
					return "等待（Waiting）";
				}
			}
			return "未知状态（Unknown Status）";
		}

		[SuppressUnmanagedCodeSecurity]
		[DllImport("winspool.Drv", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
		internal static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPTStr)] string printerName, out IntPtr phPrinter, ref CSPrinterState.structPrinterDefaults pd);

		[SuppressUnmanagedCodeSecurity]
		[DllImport("winspool.Drv", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
		internal static extern bool ClosePrinter(IntPtr phPrinter);

		[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern bool GetPrinter(IntPtr handle, int level, IntPtr buffer, int size, out int sizeNeeded);

		private static CSPrinterState.PRINTER_INFO_2 GetPrinterInfoByName(string PrinterName)
		{
			CSPrinterState.PRINTER_INFO_2 result = default(CSPrinterState.PRINTER_INFO_2);
			CSPrinterState.structPrinterDefaults structPrinterDefaults = default(CSPrinterState.structPrinterDefaults);
			IntPtr intPtr;
			if (CSPrinterState.OpenPrinter(PrinterName, out intPtr, ref structPrinterDefaults))
			{
				int num = 0;
				bool printer = CSPrinterState.GetPrinter(intPtr, 2, IntPtr.Zero, 0, out num);
				if (num > 0)
				{
					IntPtr intPtr2 = Marshal.AllocHGlobal(num);
					printer = CSPrinterState.GetPrinter(intPtr, 2, intPtr2, num, out num);
					if (printer)
					{
						result = (CSPrinterState.PRINTER_INFO_2)Marshal.PtrToStructure(intPtr2, typeof(CSPrinterState.PRINTER_INFO_2));
					}
					Marshal.FreeHGlobal(intPtr2);
				}
				CSPrinterState.ClosePrinter(intPtr);
			}
			return result;
		}

		internal static int GetPrinterStatusInt(string PrinterName)
		{
			return (int)CSPrinterState.GetPrinterInfoByName(PrinterName).Status;
		}

		internal static string GetPrinterDriverName(string PrinterName)
		{
			return CSPrinterState.GetPrinterInfoByName(PrinterName).pDriverName;
		}

		[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
		internal struct structPrinterDefaults
		{
			[MarshalAs(UnmanagedType.LPTStr)]
			public string pDatatype;

			public IntPtr pDevMode;

			[MarshalAs(UnmanagedType.I4)]
			public int DesiredAccess;
		}

		[Flags]
		internal enum PrinterStatus
		{
			PRINTER_STATUS_BUSY = 512,
			PRINTER_STATUS_DOOR_OPEN = 4194304,
			PRINTER_STATUS_ERROR = 2,
			PRINTER_STATUS_INITIALIZING = 32768,
			PRINTER_STATUS_IO_ACTIVE = 256,
			PRINTER_STATUS_MANUAL_FEED = 32,
			PRINTER_STATUS_NO_TONER = 262144,
			PRINTER_STATUS_NOT_AVAILABLE = 4096,
			PRINTER_STATUS_OFFLINE = 128,
			PRINTER_STATUS_OUT_OF_MEMORY = 2097152,
			PRINTER_STATUS_OUTPUT_BIN_FULL = 2048,
			PRINTER_STATUS_PAGE_PUNT = 524288,
			PRINTER_STATUS_PAPER_JAM = 8,
			PRINTER_STATUS_PAPER_OUT = 16,
			PRINTER_STATUS_PAPER_PROBLEM = 64,
			PRINTER_STATUS_PAUSED = 1,
			PRINTER_STATUS_PENDING_DELETION = 4,
			PRINTER_STATUS_PRINTING = 1024,
			PRINTER_STATUS_PROCESSING = 16384,
			PRINTER_STATUS_TONER_LOW = 131072,
			PRINTER_STATUS_USER_INTERVENTION = 1048576,
			PRINTER_STATUS_WAITING = 536870912,
			PRINTER_STATUS_WARMING_UP = 65536
		}

		public struct PRINTER_INFO_2
		{
			[MarshalAs(UnmanagedType.LPTStr)]
			public string pServerName;

			[MarshalAs(UnmanagedType.LPTStr)]
			public string pPrinterName;

			[MarshalAs(UnmanagedType.LPTStr)]
			public string pShareName;

			[MarshalAs(UnmanagedType.LPTStr)]
			public string pPortName;

			[MarshalAs(UnmanagedType.LPTStr)]
			public string pDriverName;

			[MarshalAs(UnmanagedType.LPTStr)]
			public string pComment;

			[MarshalAs(UnmanagedType.LPTStr)]
			public string pLocation;

			public IntPtr pDevMode;

			[MarshalAs(UnmanagedType.LPTStr)]
			public string pSepFile;

			[MarshalAs(UnmanagedType.LPTStr)]
			public string pPrintProcessor;

			[MarshalAs(UnmanagedType.LPTStr)]
			public string pDatatype;

			[MarshalAs(UnmanagedType.LPTStr)]
			public string pParameters;

			public IntPtr pSecurityDescriptor;

			public uint Attributes;

			public uint Priority;

			public uint DefaultPriority;

			public uint StartTime;

			public uint UntilTime;

			public uint Status;

			public uint cJobs;

			public uint AveragePPM;
		}
	}
}
